home *** CD-ROM | disk | FTP | other *** search
- /*
- * NOTES:
- * 1. mrti() assumes unsigned short is 2 bytes, MSB first
- * this may have to change for other architecture
- * 2. will it be possible to increase the encoded float array length
- * by "adding l" to create 256 aggregates of 3 or 4 floats each, as
- * opposed to 256 straight floats? (see appendix C, pg 163 of the
- * 'big' renderman manual)
- * 3. the name mrti should be changed to mgri (it sounds better)
- */
-
- #include "mgribtoken.h"
- #include <stdio.h>
-
- #include "mg.h"
- #include "mgribP.h"
- #include "mgrib.h"
-
- #ifdef test
- #include <stdio.h>
- #endif
-
- #define BUFFERSIZE 1024*128 /* 128k buffer */
- #define TMPSIZE 8192
- #define SECTIONWIDTH 70 /* width of a section header */
-
- #define STRINGDEF 0315
- #define STRINGREF 0317
- #define LNGSTRINGENCODE 0241 /* length follows, is unsigned short */
- #define STRINGENCODE 0220
- #define RIREQDEF 0314
- #define RIREQREF 0246
- #define FLOATARRAYDEF 0310
- #define INTEGER 0201 /* unsigned short */
- #define FLOAT 0244
-
- void binary_token(int a1, va_list *alist);
- void ascii_token(int a1, va_list *alist);
-
- unsigned char *tokenbuffer=NULL;
- unsigned char *limit;
- unsigned char *ptr;
-
- /* following is the table: see mgribtoken.h (struct) for desc of fields */
- static struct _table table[] = {
- {"", 0, 0, 0}, /* mr_NULL */
-
- /* Ri Requests */
- {"AttributeBegin", 14, 0, 0},
- {"AttributeEnd", 12, 1, 0},
- {"TransformBegin", 14, 2, 0},
- {"TransformEnd", 12, 3, 0},
- {"Identity", 8, 4, 0},
- {"ConcatTransform", 15, 5, 0},
- {"Surface", 7, 6, 0},
- {"ShadingInterpolation", 20, 7, 0},
- {"Color", 5, 8, 0},
- {"Opacity", 7, 9, 0},
- {"Polygon", 7, 10, 0},
- {"PatchMesh", 9, 11, 0},
- {"Format", 6, 12, 0},
- {"Projection", 10, 13, 0},
- {"Clipping", 8, 14, 0},
- {"WorldBegin", 10, 15, 0},
- {"WorldEnd", 8, 16, 0},
- {"Display", 7, 17, 0},
- {"ScreenWindow", 12, 19, 0},
- {"LightSource", 11, 20, 0},
- {"Sphere", 6, 21, 0},
- {"Translate", 9, 22, 0},
- {"Rotate", 6, 23, 0},
- {"Cylinder", 8, 24, 0},
- {"NuPatch", 7, 25, 0},
- {"ShadingRate", 11, 26, 0},
- {"Option", 6, 27, 0},
- {"Illuminate", 10, 28, 0},
- {"FrameBegin", 10, 29, 0},
- {"FrameEnd", 8, 30, 0},
-
- /* following are reserved - do not add */
- /* or remove fields, just change them! */
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
- {"", 0, 255, 0},
-
- /* Strings - we start these out at position 50 */
- {"P", 1, 0, 0},
- {"N", 1, 1, 0},
- {"Cs", 2, 2, 0},
- {"Pw", 2, 3, 0},
- {"Os", 2, 4, 0},
- {"st", 2, 5, 0},
- {"plastic", 7, 6, 0},
- {"hplastic", 8, 7, 0},
- {"eplastic", 8, 8, 0},
- {"heplastic", 9, 9, 0},
- {"constant", 8, 10, 0},
- {"ambientlight", 12, 11, 0},
- {"lightcolor", 10, 12, 0},
- {"distantlight", 12, 13, 0},
- {"intensity", 9, 14, 0},
- {"file", 4, 15, 0},
- {"rgb", 3, 16, 0},
- {"rgba", 4, 17, 0},
- {"Ka", 2, 18, 0},
- {"Kd", 2, 19, 0},
- {"Ks", 2, 20, 0},
- {"specularcolor", 13, 21, 0},
- {"roughness", 9, 22, 0},
- {"fov", 3, 23, 0},
- {"perspective", 11, 24, 0},
- {"to", 2, 25, 0},
- {"framebuffer", 11, 26, 0}
- };
-
- /* initialize tokenbuffer */
- void mrti_init()
- {
- if(tokenbuffer) free(tokenbuffer);
- tokenbuffer = (unsigned char *)malloc(BUFFERSIZE);
- tokenbuffer[0] = (char)0;
- limit = (unsigned char *)(tokenbuffer + BUFFERSIZE);
- ptr = tokenbuffer;
- }
-
- /* reset the ptr & tokenbuffer */
- void mrti_reset()
- {
- ptr = tokenbuffer;
- tokenbuffer[0] = (char)0;
- }
-
- /* quick copy routine w/ ptr update */
- void cat(unsigned char *s, char *a)
- {
- while(*(s++)=(*(a++))) ptr++;
- }
-
-
- /* routine will check buffer for possible overun, will realloc if needed */
- /* generally, "worst case" values should be passed to check_buffer */
- void check_buffer(int length)
- {
- if((unsigned char *)(ptr+length)>(unsigned char *)limit) {
- /* optinally check for maximum buffer allocation here */
- long used = ptr - tokenbuffer;
- long avail = limit - tokenbuffer;
- /* Buffer grows exponentially, by factor of 1.5 each time */
- do { avail += avail>>1; } while(used+length >= avail);
- tokenbuffer = (unsigned char *)realloc(tokenbuffer, avail);
- ptr = tokenbuffer + used;
- limit = tokenbuffer + avail;
- }
- }
-
- /* process variable size token list */
- void mrti(int a1, ... )
- {
- va_list alist;
-
- va_start(alist, a1);
-
- switch((int)(_mgribc->render_device & (RMD_BINARY|RMD_ASCII)))
- {
- case (int)RMD_BINARY: binary_token(a1, &alist); break;
- case (int)RMD_ASCII: ascii_token(a1, &alist); break;
- }
- va_end(alist);
- }
-
- /* return 1 when supplied token requires its own (ascii) line, 0 otherwise */
- int line_initializer(int token)
- {
- /* THIS IS HACKISH - IT WILL CREATE A LINE FEED BEFORE */
- /* IT CREATES THE NEW LINE, WHICH ISN'T ALWAYS GOOD!! */
- if(token<STRINGBASE||token==mr_comment||token==mr_section||
- (token>=mr_P && token<=mr_Os)) return 1;
- else return 0;
- }
-
- /* ASCII SUBPROCESSING */
- void ascii_token(int token, va_list *alist)
- {
- int i;
- int count, number;
- int subsize;
- static int arraysize;
- static int expectSubArray=0;
- static char astring[128];
- double nextfloat; /* va_arg converts floats to doubles */
- float *floatptr;
- char *s;
- int len, add;
-
- do {
-
- if(expectSubArray && (token!=mr_subarray3)) {
- /* ERROR */
- }
-
- /* check to see if we need to start a new line */
- if(line_initializer(token) && *(ptr-1)!='\n') *(ptr++)='\n';
-
- switch(token) {
-
- case mr_section:
- check_buffer(SECTIONWIDTH); /* should not exceed this */
- s = va_arg(*alist, char*);
- len = strlen(s);
- if(len+3>SECTIONWIDTH) len = SECTIONWIDTH-3; /* 3 added characters */
- *(ptr++)='\n';
- cat(ptr,"# ");
- cat(ptr,s);
- cat(ptr," ");
-
- len = SECTIONWIDTH - 3 - len;
- while((len--)>0) *(ptr++)='*';
- break;
-
- case mr_comment:
- s = va_arg(*alist, char*);
- len = strlen(s);
- check_buffer(len+2);
- cat(ptr,"# ");
- cat(ptr,s);
- break;
-
- case mr_header:
- s = va_arg(*alist, char*);
- len = strlen(s);
- check_buffer(len+2);
- cat(ptr,"##");
- cat(ptr,s);
- break;
-
- case mr_nl:
- /* check for space */
- check_buffer(2);
- if(*(ptr-1)==' ') ptr--;
- *(ptr++)='\n';
- break;
-
- case mr_array:
- arraysize = va_arg(*alist, int);
- check_buffer(arraysize*16+4); /* how else can we do this? */
- *(ptr++)='[';
- for(i=0;i<arraysize;i++) {
- nextfloat = va_arg(*alist, double);
- sprintf(astring,"%g ",nextfloat);
- cat(ptr, astring);
- }
- *(--ptr)=0; /* get rid of space */
- cat(ptr,"] ");
- break;
-
- case mr_buildarray:
- arraysize = va_arg(*alist, int);
- check_buffer(1);
- expectSubArray = 1;
- *(ptr++)='[';
- break;
-
- case mr_parray:
- {
- int size;
- size = va_arg(*alist, int);
- check_buffer(2+16*size);
- *(ptr++)='[';
- /* if arraysize<0 then ERROR */
- floatptr = va_arg(*alist, float*);
- for(i=0;i<size;i++) {
- sprintf(astring,"%g ",*(floatptr++));
- cat(ptr,astring);
- }
- *(--ptr)=0; /* get rid of unwanted space */
- cat(ptr,"] ");
- break;
- }
-
- case mr_subarray3:
- check_buffer(16*3+7);
- arraysize-=3;
- /* if arraysize<0 then ERROR */
- floatptr = va_arg(*alist, float*);
- sprintf(astring,"%g %g %g ",
- *(floatptr),*(floatptr+1),*(floatptr+2));
- cat(ptr,astring);
- if(arraysize<=0) {
- expectSubArray = 0;
- *(ptr-=3)=0; /* get rid of unwanted spaces */
- cat(ptr,"] ");
- }
- break;
-
- case mr_int:
- number = va_arg(*alist, int);
- check_buffer(16);
- sprintf(astring,"%d ",number);
- cat(ptr,astring);
- break;
-
- case mr_float:
- nextfloat = va_arg(*alist, double);
- check_buffer(16);
- sprintf(astring,"%g ",nextfloat);
- cat(ptr,astring);
- break;
-
- case mr_intseq:
- /* OBSOLETE */
- count = va_arg(*alist, int);
- check_buffer(count*16);
- for(i=0;i<count;i++) {
- number = va_arg(*alist, int);
- sprintf(astring,"%d ",number);
- cat(ptr,astring);
- }
- *(--ptr)=0;
- break;
-
- case mr_string:
- {
- char *string;
- string = va_arg(*alist, char *);
- len = strlen(string);
- check_buffer(len+3);
- *(ptr++)='"';
- cat(ptr,string);
- *(ptr++)='"';
- *(ptr++)=' ';
- break;
- }
-
- case mr_embed:
- {
- /* directly embed a string */
- char *string;
- string = va_arg(*alist, char *);
- len = strlen(string);
- check_buffer(len);
- cat(ptr,string);
- break;
- }
- /* these requests require a trailing line feed */
- case mr_attributebegin:
- case mr_attributeend:
- case mr_transformbegin:
- case mr_transformend:
- case mr_identity:
- case mr_polygon:
- case mr_worldbegin:
- case mr_worldend:
- case mr_frameend:
- check_buffer(table[token].len);
- cat(ptr,table[token].name);
- /*
- *(ptr++) = '\n';
- */
- break;
-
- /* these requests require a trailing space */
- case mr_color:
- case mr_opacity:
- case mr_format:
- case mr_display:
- case mr_screenwindow:
- case mr_clipping:
- case mr_concattransform:
- case mr_projection:
- case mr_lightsource:
- case mr_illuminate:
- case mr_surface:
- case mr_sphere:
- case mr_patchmesh:
- case mr_rotate:
- case mr_translate:
- case mr_cylinder:
- case mr_nupatch:
- case mr_option:
- case mr_shadinginterpolation:
- case mr_shadingrate:
- case mr_framebegin:
- check_buffer(table[token].len+1);
- cat(ptr,table[token].name);
- *(ptr++)=' ';
- break;
-
- /* anything left over should be a string */
- /* which requires quotes & trailing space */
- /* (THIS SHOULD BE MOVED OUT OF SWITCH) */
- default:
- check_buffer(table[token].len+3);
- *(ptr++)='"';
- cat(ptr,table[token].name);
- *(ptr++)='"';
- *(ptr++)=' ';
- break;
-
- }
-
- } while ((token=va_arg(*alist, int))!=mr_NULL);
- }
-
-
- /* BINARY SUBPROCESSING */
- /* NOTE: some hardware will not support copying data types > 1 byte into an
- * arbitrary (unaligned) location. e.g.
- * *(unsigned short *)ptr = anUnsignedVariable
- * may be an illegal instruction. Therefore, macros which will copy these
- * values one byte at a time follow here and are used where needed. These
- * macros will work only with float sizes of 4 bytes (IEEE) & unsigned short
- * int sizes of 2 bytes
- */
-
- #define COPYUSHORT( value ) *ptr++ = ((char *)&value)[0];\
- *ptr++ = ((char *)&value)[1]
- #define COPYFLOAT( value ) *ptr++ = ((char *)&value)[0];\
- *ptr++ = ((char *)&value)[1];\
- *ptr++ = ((char *)&value)[2];\
- *ptr++ = ((char *)&value)[3]
-
- void binary_token(int token, va_list *alist)
- {
- int i;
- static int expectSubArray=0;
- static int arraysize;
- float *floatptr;
-
- if(expectSubArray && (token!=mr_subarray3)) {
- /* ERROR */
- }
-
- do {
-
- if(token>=STRINGBASE & token<mr_array) {
- /* The token is a string defintion/request */
- if(!table[token].defined) {
- check_buffer(7 + table[token].len);
- *(ptr++)=STRINGDEF;
- *(ptr++)=table[token].reqn;
- if(table[token].len<16) {
- *(ptr++)=STRINGENCODE+table[token].len;
- } else {
- unsigned short length;
- length = (unsigned short) table[token].len;
- *(ptr++)=LNGSTRINGENCODE;
- COPYUSHORT(length);
- }
- cat(ptr,table[token].name);
- table[token].defined = 1;
- }
- *(ptr++)=STRINGREF;
- *(ptr++)=table[token].reqn;
- }
-
- else switch(token) {
-
- /* THESE SHOULD BE MOVE BEFORE SWITCH */
- /* AND TURNED INTO A SPECIAL CASE */
- case mr_attributebegin:
- case mr_attributeend:
- case mr_transformbegin:
- case mr_transformend:
- case mr_identity:
- case mr_polygon:
- case mr_worldbegin:
- case mr_worldend:
- case mr_color:
- case mr_format:
- case mr_display:
- case mr_screenwindow:
- case mr_clipping:
- case mr_concattransform:
- case mr_projection:
- case mr_lightsource:
- case mr_illuminate:
- case mr_surface:
- case mr_sphere:
- case mr_patchmesh:
- case mr_translate:
- case mr_rotate:
- case mr_cylinder:
- case mr_nupatch:
- case mr_option:
- case mr_shadinginterpolation:
- case mr_shadingrate:
- case mr_framebegin:
- case mr_frameend:
- check_buffer(7+table[token].len);
- if(!table[token].defined) {
- /* we must define it */
- *(ptr++)=RIREQDEF;
- *(ptr++)=table[token].reqn;
- if(table[token].len<16) {
- *(ptr++)=STRINGENCODE+table[token].len;
- } else {
- unsigned short length;
- length = (unsigned short) table[token].len;
- *(ptr++)=LNGSTRINGENCODE;
- COPYUSHORT(length);
- }
- cat(ptr,table[token].name);
- table[token].defined = 1;
- }
- *(ptr++)=RIREQREF;
- *(ptr++)=table[token].reqn;
- break;
-
- case mr_array:
- {
- unsigned char arraycount;
- unsigned char *p;
- float f;
- arraycount = (unsigned char)va_arg(*alist, int);
- check_buffer(2+4*arraycount);
- *(ptr++)=FLOATARRAYDEF;
- *(ptr++)=arraycount;
- for(i=0;i<arraycount;i++) {
- /* will float be the same on each platform? (ieee?)*/
- /* IS THIS NEXT STEP LEGAL?!? */
- f = (float) va_arg(*alist, double);
- COPYFLOAT(f);
- }
- break;
- }
-
- case mr_buildarray:
- {
- unsigned char arraycount;
- arraysize = va_arg(*alist, int);
- arraycount = (unsigned char)arraysize;
- check_buffer(2);
- *(ptr++)=FLOATARRAYDEF;
- *(ptr++)=arraycount;
- expectSubArray = 1;
- break;
- }
-
- case mr_subarray3:
- {
- arraysize-=3;
- if(arraysize<0) /* ERROR */;
- check_buffer(12); /* 3*sizeof(float) */
- floatptr = va_arg(*alist, float*);
- bcopy((char *)floatptr, (char *)ptr, 3*sizeof(float));
- ptr+=3*sizeof(float);
- if(arraysize<=0) {
- expectSubArray = 0;
- }
- break;
- }
-
- case mr_parray:
- {
- unsigned char arraycount;
- arraycount = (unsigned char)va_arg(*alist, int);
- check_buffer(2+arraycount*4);
- *(ptr++)=FLOATARRAYDEF;
- *(ptr++)=arraycount;
- floatptr = va_arg(*alist, float*);
- bcopy((char *)floatptr, (char *)ptr, arraycount*sizeof(float));
- ptr+=arraycount*sizeof(float);
- if(arraysize<=0) {
- expectSubArray = 0;
- }
- break;
- }
-
- case mr_int:
- {
- unsigned short number;
- check_buffer(3);
- number = (unsigned short)va_arg(*alist, int);
- *(ptr++) = INTEGER;
- COPYUSHORT(number);
- break;
- }
-
- case mr_float:
- {
- float afloat;
- check_buffer(5);
- afloat = (float)va_arg(*alist, double);
- *(ptr++) = FLOAT;
- COPYFLOAT(afloat);
- break;
- }
-
- case mr_intseq:
- {
- /* OBSOLETE */
- unsigned short number;
- int count;
- count = va_arg(*alist, int);
- check_buffer(number*2);
- for(i=0;i<count;i++) {
- number = (unsigned short)va_arg(*alist, int);
- *(ptr++) = INTEGER;
- COPYUSHORT(number);
- }
- break;
- }
-
- case mr_string:
- {
- unsigned short length;
- char *string;
- string = va_arg(*alist, char *);
- length = (unsigned short) strlen(string);
- check_buffer(3+length);
- if(length<16) {
- *(ptr++)=STRINGENCODE+(char)length;
- } else {
- *(ptr++)=LNGSTRINGENCODE;
- COPYUSHORT(length);
- }
- cat(ptr,string);
- break;
- }
-
- case mr_embed:
- {
- /* no attempt is made to encode this becuase it's so general */
- char *string;
- int length;
- string = va_arg(*alist, char *);
- length = strlen(string);
- check_buffer(length);
- cat(ptr,string);
- break;
- }
-
- case mr_nl:
- /* temporary for debugging (puts tokens on spereate lines) */
- /* printf("\n"); */
- break;
-
- } /* switch */
- } while ((token=va_arg(*alist, int))!=mr_NULL);
- }
-